import tkinter as tk
from tkinter import ttk, messagebox
import tkinter.scrolledtext as scrolledtext

from pubsub import pub

# 保持原有导入不变
from zhi_dao.entity.zhidao_course import ZhiDaoCourse
from zhi_dao.entity.zhidao_section import ZhiDaoSection
from zhi_dao.player.zhidao_video_player import ZhiDaoVideoPlayer
from zhi_dao.selector.zhidao_course_selector import ZhiDaoCourseSelector
from zhi_dao.selector.zhidao_section_selector import ZhiDaoSectionSelector
from zhi_dao.zhidao_const import (event_course_read_success, event_login,
                                  event_section_read_finished, event_ui_exit,
                                  event_video_progress_done, event_video_progress_updated,
                                  event_video_safe_verify_shown)


class ZhiDaoUI:
    # 保持原有变量定义
    process_var = None
    step = 0
    window = None
    username_para = None
    password_para = None
    comb = None  # 课程选择下拉框
    section_comb = None  # 小节选择下拉框
    video_play_btn = None
    video_player = None
    progress_para = None
    course_selector: ZhiDaoCourseSelector
    section_selector: ZhiDaoSectionSelector
    status_frame = None
    status_label = None
    operation_frame = None
    control_frame = None
    # process_btn = None
    progress_label = None
    progress_bar = None
    courses = None  # 缓存课程列表，用于重新选择课程
    current_course_name = None

    def __init__(self):
        self.video_player = ZhiDaoVideoPlayer()
        # 订阅事件保持不变
        pub.subscribe(self.read_courses, event_course_read_success)
        pub.subscribe(self.read_sections, event_section_read_finished)
        pub.subscribe(self.update_progress, event_video_progress_updated)
        pub.subscribe(self.video_finished, event_video_progress_done)
        pub.subscribe(self.video_safe_verify_notify, event_video_safe_verify_shown)

        # 主窗口初始化
        self.window = tk.Tk()
        self.window.title('知到课程助手')
        self.window.geometry('900x600')
        self.window.resizable(True, True)

        # 配置网格布局权重
        self.window.grid_rowconfigure(0, weight=1)
        self.window.grid_columnconfigure(0, weight=1)

        # 创建主容器
        self.main_frame = ttk.Frame(self.window, padding="20 20 20 20")
        self.main_frame.grid(row=0, column=0, sticky="nsew")
        self.main_frame.grid_rowconfigure(0, weight=1)
        self.main_frame.grid_columnconfigure(0, weight=1)

        # 状态变量初始化
        self.progress_para = tk.StringVar(value="0%")
        self.process_var = tk.StringVar(value="开始")

        # 初始化界面分区
        self.init_ui_sections()

        self.window.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.window.mainloop()

    def init_ui_sections(self):
        """初始化界面分区容器"""
        # 1. 操作状态区
        self.status_frame = ttk.LabelFrame(self.main_frame, text="操作状态", padding="10 10 10 10")
        self.status_frame.grid(row=0, column=0, sticky="ew", pady=(0, 10))
        self.status_frame.grid_columnconfigure(0, weight=1)

        # 状态提示标签
        self.status_label = ttk.Label(self.status_frame, text="请点击开始按钮进入流程")
        self.status_label.grid(row=0, column=0, sticky="w", padx=5)

        # 2. 主操作区
        self.operation_frame = ttk.LabelFrame(self.main_frame, text="主操作区", padding="15 15 15 15")
        self.operation_frame.grid(row=1, column=0, sticky="nsew", pady=(0, 10))
        self.operation_frame.grid_rowconfigure(0, weight=1)
        self.operation_frame.grid_columnconfigure(0, weight=1)

        # 3. 进度与控制区
        self.control_frame = ttk.LabelFrame(self.main_frame, text="进度与控制", padding="10 10 10 10")
        self.control_frame.grid(row=2, column=0, sticky="ew")
        self.control_frame.grid_columnconfigure(0, weight=1)
        self.start()
        # # 开始按钮
        # self.process_btn = ttk.Button(
        #     self.control_frame,
        #     textvariable=self.process_var,
        #     command=self.start,
        #     width=15
        # )
        # self.process_btn.grid(row=0, column=1, padx=10, pady=5)

        # 进度显示
        # ttk.Label(self.control_frame, text="当前进度：").grid(row=0, column=0, sticky="e", padx=(0, 5))
        self.progress_bar = ttk.Progressbar(
            self.control_frame,
            orient="horizontal",
            length=200,
            mode="determinate"
        )
        self.progress_bar.grid(row=1, column=0, columnspan=2, pady=10, padx=10, sticky="ew")

    def step_input_account(self, username: str, password: str):
        """账号密码输入区域布局"""
        if self.step >= 1:
            return

        # 清空操作区
        self.clear_operation_frame()

        # 更新状态提示
        self.status_label.config(text="请输入账号密码并登录")

        # 创建账号密码输入表单
        input_frame = ttk.Frame(self.operation_frame)
        input_frame.grid(row=0, column=0, padx=50, pady=30)

        # 用户名输入行
        ttk.Label(input_frame, text="用户名：", width=10).grid(row=0, column=0, sticky="e", pady=10)
        self.username_para = tk.StringVar(value=username)
        username_input = ttk.Entry(input_frame, textvariable=self.username_para, width=30)
        username_input.grid(row=0, column=1, pady=10)

        # 密码输入行
        ttk.Label(input_frame, text="密码：", width=10).grid(row=1, column=0, sticky="e", pady=10)
        self.password_para = tk.StringVar(value=password)
        password_input = ttk.Entry(input_frame, textvariable=self.password_para, show="*", width=30)
        password_input.grid(row=1, column=1, pady=10)

        # 登录按钮
        login_btn = ttk.Button(input_frame, text="登录", command=self.login, width=15)
        login_btn.grid(row=2, column=0, columnspan=2, pady=20)

    def start(self):
        """开始按钮逻辑"""
        if self.step == 0:
            self.step_input_account("15311674105", "511021GthxD")
            self.process_var.set("下一步")
            self.step += 1
        elif self.step == 1 and hasattr(self, 'comb') and self.comb is not None and self.comb.winfo_exists():
            # 从课程选择页进入小节加载
            self.on_course_select(None)  # 触发小节加载
        # 其他步骤可根据需要扩展

    def login(self):
        """登录逻辑"""
        self.status_label.config(text="登录中，请稍候...")
        self.window.update()
        pub.sendMessage(event_login, username=self.username_para.get(), password=self.password_para.get())

    def read_courses(self, courses: list[ZhiDaoCourse]):
        """课程选择区域布局（缓存课程列表）"""
        # 清空操作区
        self.clear_operation_frame()

        # 缓存课程列表，用于后续重新选择
        self.courses = courses.copy()

        self.status_label.config(text="请选择需要学习的课程")
        self.course_selector = ZhiDaoCourseSelector(courses)

        # 课程选择区域
        course_frame = ttk.Frame(self.operation_frame)
        course_frame.grid(row=0, column=0, sticky="nsew", padx=20, pady=20)
        course_frame.grid_rowconfigure(0, weight=1)
        course_frame.grid_columnconfigure(0, weight=1)

        # 课程选择标签
        ttk.Label(course_frame, text="可选课程（含进度）：").grid(row=0, column=0, sticky="w", pady=(0, 10))

        # 课程下拉框
        course_name_list = list(map(self.get_course_name, courses))
        self.comb = ttk.Combobox(
            course_frame,
            values=course_name_list,
            width=60,
            state="readonly"
        )
        self.comb.bind("<<ComboboxSelected>>", self.on_course_select)
        self.comb.grid(row=1, column=0, sticky="ew", pady=(0, 10))

        # 课程说明
        if courses:
            desc = f"共发现 {len(courses)} 门课程，请选择后点击下一步"
        else:
            desc = "未获取到课程列表，请检查网络连接"
        ttk.Label(course_frame, text=desc, foreground="gray").grid(row=2, column=0, sticky="w")

        self.step = 1  # 更新步骤为课程选择

    @staticmethod
    def get_course_name(course: ZhiDaoCourse):
        return course.name + " " + course.progress

    def on_course_select(self, event):
        """选中课程后加载小节"""
        if not hasattr(self, 'comb') or self.comb is not None and self.comb.winfo_exists() == 0 or not self.courses:
            self.status_label.config(text="课程选择控件已失效，请重新加载课程")
            return

        current_course_index = self.comb.current()
        if current_course_index == -1:
            self.status_label.config(text="请选择有效的课程")
            return

        try:
            course_name = self.comb.get()
            self.current_course_name = course_name
            self.status_label.config(text=f"已选择：{course_name}，正在加载小节列表...")
            self.process_var.set("加载小节")
            # 触发小节加载（实际项目中这里应该是调用接口获取该课程的小节）
            self.course_selector.select_course(current_course_index)
        except tk.TclError:
            self.status_label.config(text="获取课程信息失败，请重试")

    def read_sections(self, sections: list[ZhiDaoSection]):
        """小节选择区域布局（增加课程重新选择功能）"""
        # 清空操作区
        self.clear_operation_frame()

        self.status_label.config(text="请选择需要播放的课程小节")
        self.section_selector = ZhiDaoSectionSelector(sections)

        # 小节选择区域
        section_frame = ttk.Frame(self.operation_frame)
        section_frame.grid(row=0, column=0, sticky="nsew", padx=20, pady=20)
        section_frame.grid_rowconfigure(1, weight=1)  # 让课程选择区可拉伸
        section_frame.grid_columnconfigure(0, weight=1)

        # 顶部课程重新选择区
        course_reselect_frame = ttk.Frame(section_frame)
        course_reselect_frame.grid(row=0, column=0, sticky="ew", pady=(0, 15))
        course_reselect_frame.grid_columnconfigure(1, weight=1)

        ttk.Label(course_reselect_frame, text="当前课程：").grid(row=0, column=0, sticky="e", padx=(0, 5))

        # 显示当前选中的课程名称
        current_course = self.current_course_name
        self.current_course_label = ttk.Label(course_reselect_frame, text=current_course)
        self.current_course_label.grid(row=0, column=1, sticky="w", padx=5)

        # 重新选择课程按钮
        self.reselect_course_btn = ttk.Button(
            course_reselect_frame,
            text="重新选择课程",
            command=self.reselect_course,
            width=15
        )
        self.reselect_course_btn.grid(row=0, column=2, padx=10)

        # 小节选择标签
        ttk.Label(section_frame, text="课程小节：").grid(row=1, column=0, sticky="w", pady=(0, 10))

        # 小节下拉框
        section_name_list = list(map(self.get_section_name, sections))
        self.section_comb = ttk.Combobox(
            section_frame,
            values=section_name_list,
            width=80,
            state="readonly"
        )
        self.section_comb.bind("<<ComboboxSelected>>", self.on_section_select)
        self.section_comb.grid(row=2, column=0, sticky="ew", pady=(0, 15))

        # 播放控制区
        control_btn_frame = ttk.Frame(section_frame)
        control_btn_frame.grid(row=3, column=0, sticky="w")

        self.video_play_btn = ttk.Button(
            control_btn_frame,
            text="播放选中小节",
            command=self.play_video,
            width=15
        )
        self.video_play_btn.pack(side="left", padx=5)

        # 自动播放下一节复选框
        self.auto_play_var = tk.BooleanVar(value=True)
        ttk.Checkbutton(
            control_btn_frame,
            text="自动播放下一节",
            variable=self.auto_play_var
        ).pack(side="left", padx=15)

        self.step = 2  # 更新步骤为小节选择

    def reselect_course(self):
        """重新选择课程（直接刷新为课程选择界面）"""
        if self.courses:  # 利用缓存的课程列表快速刷新界面
            self.read_courses(self.courses)
        else:
            # 如果没有缓存，提示重新加载
            self.status_label.config(text="课程列表已失效，请重新登录加载")
            messagebox.info("提示", "请重新登录获取课程列表")
            self.step = 0
            self.process_var.set("开始")

    def get_section_name(self, section: ZhiDaoSection):
        return section.get_content()

    def on_section_select(self, event):
        current_section_index = self.section_comb.current()
        self.section_selector.select_section(current_section_index)
        self.status_label.config(text=f"已选择小节：{self.section_comb.get()}")

    def play_video(self):
        self.status_label.config(text=f"正在播放：{self.section_comb.get()}")
        self.video_player.play_video()

    def update_progress(self, progress: str):
        """更新进度条和状态"""
        try:
            progress_val = float(progress)
            self.progress_bar['value'] = progress_val
            self.progress_para.set(f"{progress}%")
            self.status_label.config(text=f"播放中：{self.section_comb.get()}（{progress}%）")
            self.control_frame.update_idletasks()
        except (ValueError, tk.TclError):
            # 处理进度值无效或控件已销毁的情况
            pass

    def video_finished(self):
        """播放完成逻辑"""
        current_index = self.section_comb.current()
        total = len(self.section_comb['values'])

        if current_index >= total - 1:
            self.progress_bar['value'] = 100
            self.progress_para.set("100%")
            self.status_label.config(text="当前课程所有小节已完成！")
            messagebox.showinfo("完成提示", "恭喜，当前课程所有小节已学习完成！")
            return

        if self.auto_play_var.get():
            self.progress_bar['value'] = 0
            self.progress_para.set("0%")
            next_section = self.section_comb['values'][current_index + 1]
            self.section_comb.set(next_section)
            self.section_comb.event_generate("<<ComboboxSelected>>")
            self.status_label.config(text=f"自动切换到下一节：{next_section}")
            self.play_video()
        else:
            self.status_label.config(text=f"当前小节已完成，请选择下一节播放")

    def video_safe_verify_notify(self):
        """安全验证提示"""
        self.progress_para.set("需要验证")
        self.status_label.config(text="检测到安全验证，等待自动处理安全验证")

    def clear_operation_frame(self):
        """清空操作区并重置控件引用"""
        for widget in self.operation_frame.winfo_children():
            widget.destroy()
        # 重置可能被销毁的控件引用
        if hasattr(self, 'comb'):
            self.comb = None
        if hasattr(self, 'section_comb'):
            self.section_comb = None

    @staticmethod
    def on_closing():
        if messagebox.askokcancel("退出", "确定要退出知到课程助手吗？"):
            pub.sendMessage(event_ui_exit)
            # 关闭窗口
            for window in tk._default_root.winfo_children():
                window.destroy()
            tk._default_root.destroy()
